package jhunter.rt.conf.ext;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import jhunter.common.exception.ConfigException;
import jhunter.common.groovy.GroovyLoader;
import jhunter.conf.actions.vo.Action;
import jhunter.rt.conf.Node;
import jhunter.rt.conf.Reloadable;
import jhunter.template.TemplateLoader;
import jhunter.web.mvc.controller.Controller;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.permission.WildcardPermission;

public class ActionExt implements Reloadable {

	private org.apache.commons.logging.Log log = LogFactory.getLog(ActionExt.class);

	private static Map<ActionExt, Class<? extends Controller>> classMap = new ConcurrentHashMap<ActionExt, Class<? extends Controller>>();

	private Action action;

	private Node actionNode;

	public ActionExt(Action action, Node actionNode) {
		super();
		this.action = action;
		this.actionNode = actionNode;
	}

	public Permission getPermission() {
		ModuleExt module = (ModuleExt) actionNode.getParent().getParent().getObject();
		AppExt app = (AppExt) actionNode.getParent().getParent().getParent().getObject();
		/**
		 * appid:moduleid:actionName
		 */
		String p = "action:" + app.getApp().getId() + ":" + module.getModule().getId() + ":" + this.action.getName();
		WildcardPermission permission = new WildcardPermission(p);
		return permission;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected Class getGroovyControllerClass() {
		if (classMap.containsKey(this)) {
			return classMap.get(this);
		}
		if(StringUtils.isNotBlank(action.getClazz())) {
			try {
				Class clazz = Class.forName(action.getClazz().trim());
				classMap.put(this, clazz);
				return clazz;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				throw new ConfigException(e);
			}
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("random", System.currentTimeMillis());
		params.put("value", action.getReturn().getValue());
		params.put("services", ((ModuleExt) actionNode.getParent().getParent().getObject()).getServiceExt().getServices().getService());
		String tp = TemplateLoader.getStringByTemplate("/jhunter/web/mvc/controller/GroovyController.vm", params);
		log.debug("\n" + tp);
		Class clazz = GroovyLoader.loadClass(tp);
		classMap.put(this, clazz);
		return clazz;
	}

	public Controller getGroovyController() {
		try {
			Controller controller = (Controller) getGroovyControllerClass().newInstance();
			controller.setAction(this);
			// controller.setModuleService(((ModuleExt)
			// actionNode.getParent().getObject()).getModuleServiceMap());
			controller.setModuleExt(((ModuleExt) actionNode.getParent().getParent().getObject()));
			return controller;
		} catch (InstantiationException e) {
			e.printStackTrace();
			throw new ConfigException(e);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			throw new ConfigException(e);
		}
	}

	public Action getAction() {
		return action;
	}

	public void setAction(Action action) {
		this.action = action;
	}

	public Node getActionNode() {
		return actionNode;
	}

	public void setActionNode(Node actionNode) {
		this.actionNode = actionNode;
	}

	@Override
	public void unload() {
		classMap.remove(this);
	}

	@Override
	public void afterLoad() {

	}

	@Override
	public void init() {
		afterLoad();

	}

	private String templateDirctoryPath;
	
	public String getAppendTemplateFilePath() {
		String path = templateDirctoryPath +"/"+ "_" + action.getName() +".vm";
		File file = new File(path);
		if(file.exists()) {
			if(file.getPath().indexOf("classes") > -1) {
				return file.getPath().substring(file.getPath().indexOf("classes") + "classes".length());
			}
			return file.getPath() ; 
		}
		return null ;
	}
	
	public String getTemplateFile(String file) {
		String path = templateDirctoryPath + "/" + file + ".vm";
		return getClassPathFilePath(path) ;
	}
	
	protected String getClassPathFilePath(String path) {
		File file = new File(path);
		if(file.exists()) {
			if(file.getPath().indexOf("classes") > -1) {
				return file.getPath().substring(file.getPath().indexOf("classes") + "classes".length());
			}
			return file.getPath() ; 
		}
		return null ;
	}
	
	public String getExtendTemplateFilePath() {
		String path = templateDirctoryPath +"/"+ "_" + action.getName() +"_extend.vm";
		File file = new File(path);
		if(file.exists()) {
			if(file.getPath().indexOf("classes") > -1) {
				return file.getPath().substring(file.getPath().indexOf("classes") + "classes".length());
			}
			return file.getPath() ; 
		}
		return null ;
	}
	
	

	public String getTemplateDirctoryPath() {
		return templateDirctoryPath;
	}

	public void setTemplateDirctoryPath(String templateDirctoryPath) {
		this.templateDirctoryPath = templateDirctoryPath;
	}

}
